package com.hzgj.soa.spring;

import com.hzgj.bcl.soa.config.RegistryDef;
import com.hzgj.bcl.soa.registry.RegistryContext;
import com.hzgj.bcl.soa.registry.RegistryService;
import com.hzgj.bcl.soa.util.Constants;
import com.hzgj.bcl.util.jmx.Management;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

import lombok.Getter;

public class RegistryBean implements ApplicationContextAware {

    private final AtomicInteger refresh = new AtomicInteger();
    @Getter
    RegistryService registryService;
    private Logger logger = LoggerFactory.getLogger(getClass());
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        try {
            initRegistryService();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void registryServer(RegistryContext.ServerRegisterModel serverRegisterModel) {
        RegistryDef registryDef = applicationContext.getBean(RegistryDef.class);
        registryService.handleRegService(serverRegisterModel, refresh.get(), registryDef.getMode().equals(Constants.NOTIFY_CLIENT_PULL_MODE));
    }

    public void initRegistryService() {
        RegistryDef registryDef = applicationContext.getBean(RegistryDef.class);
        Objects.requireNonNull(registryDef.getAddress());
        String type;
        String address = "";
        String tag = "://";
        int index = registryDef.getAddress().indexOf(tag);
        if (index >= 0) {
            type = registryDef.getAddress().substring(0, index);
            address = registryDef.getAddress().substring(index + tag.length());
        } else {
            throw new RuntimeException("element[registry] attr[address] must like etcd://127.0.0.1:9090");
        }

        switch (type) {
            case Constants.ETCD_REGISTRY:
                registryDef.setProtocol(Constants.ETCD_REGISTRY);
                if (!address.isEmpty()) {
                    registryDef.setAddress(address);
                }
                break;
            case Constants.ZK_REGISTRY:
                registryDef.setProtocol(Constants.ZK_REGISTRY);
                if (!address.isEmpty()) {
                    registryDef.setAddress(address);
                }
                break;
            default:
                throw new RuntimeException("unsupport registry type");
        }
        registryService = new RegistryService(registryDef);
        refresh.set(registryDef.getRefresh());
        Management.register(registryService, Constants.getRegistryServiceObjectName());
    }
}